/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kurvykurvy.core.ui;

import com.kurvykurvy.core.KurvyDataManager;
import com.kurvykurvy.page.ImageFrame;
import com.kurvykurvy.page.PageLayoutTemplate;
import com.kurvykurvy.page.PageSpread;
import com.kurvykurvy.page.PageSpreadLayout;
import com.kurvykurvy.image.ImageFrameComponent;
import com.kurvykurvy.page.Book;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Iterator;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.TransferHandler;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.util.Exceptions;

/**
 * Top component which displays something.
 */
@ConvertAsProperties( dtd = "-//com.kurvykurvy.core.ui//KurvyLayout//EN", autostore = false )
public final class KurvyLayoutTopComponent
        extends TopComponent
        implements DropTargetListener
{
    PageSpreadLayout pageSpread;

    JLabel mask;
    JLabel decoration;

    private static KurvyLayoutTopComponent instance;
    /** path to the icon used by the component and its open action */
//    static final String ICON_PATH = "SET/PATH/TO/ICON/HERE";
    public static final String PREFERRED_ID = "KurvyLayoutTopComponent";

    public KurvyLayoutTopComponent()
    {
        initComponents();
        setName( NbBundle.getMessage( KurvyLayoutTopComponent.class, "CTL_KurvyLayoutTopComponent" ) );
        setToolTipText( NbBundle.getMessage( KurvyLayoutTopComponent.class, "HINT_KurvyLayoutTopComponent" ) );

        setBackground( Color.GRAY );
        Book currentBook = KurvyDataManager.getInstance().getCurrentBook();
        setPageSpread( currentBook.getPageSpreads().get(  0 ) );
        this.setDropTarget( new DropTarget( this, this ) );
    }

    public void setPageSpread( PageSpreadLayout layout )
    {
        this.pageSpread = layout;
        layoutPage();
    }

    public void nextPage()
    {
        Book currentBook = KurvyDataManager.getInstance().getCurrentBook();
        PageSpread nextSpread = currentBook.getNextPageSpread( (PageSpread) this.pageSpread );
        if( nextSpread != null )
        {
            setPageSpread( nextSpread );
        }
        this.updateUI();
    }

    public void previousPage()
    {
        Book currentBook = KurvyDataManager.getInstance().getCurrentBook();
        PageSpread prevSpread = currentBook.getPreviousPageSpread( (PageSpread) this.pageSpread );
        if( prevSpread != null )
        {
            setPageSpread( prevSpread );
        }
        this.updateUI();
    }

    public void addPageSpread()
    {
        Book currentBook = KurvyDataManager.getInstance().getCurrentBook();
        PageSpread newSpread = currentBook.createNewPageSpread();
        currentBook.addPageSpread( newSpread );
        nextPage();
    }

    public void layoutPage()
    {
        if( pageSpread != null )
        {
            Book currentBook = KurvyDataManager.getInstance().getCurrentBook();

            forwardButton.setEnabled(  currentBook.getNextPageSpread( (PageSpread) this.pageSpread ) != null ) ;
            backButton.setEnabled( currentBook.getPreviousPageSpread( (PageSpread) this.pageSpread ) != null );

            layoutPane.removeAll();

            Rectangle visibleRectangle = getVisibleRect();
            ImageIcon pageSpreadMaskIcon = new ImageIcon( this.pageSpread.getPageSpreadMask() );
            JLabel pageSpreadMaskLabel = new JLabel( pageSpreadMaskIcon );


            int offsetX = 0;
            int offsetY = 0;
            if( this.pageSpread.getPageSpreadMask().getWidth() <= visibleRectangle.width )
            {
                offsetX = (visibleRectangle.width - this.pageSpread.getPageSpreadMask().getWidth() )/2;
            }

            if( this.pageSpread.getPageSpreadMask().getHeight() <= visibleRectangle.height )
            {
                offsetY = ( visibleRectangle.height - this.pageSpread.getPageSpreadMask().getHeight() ) / 2;
            }

            pageSpreadMaskLabel.setBounds( offsetX, offsetY, this.pageSpread.getPageSpreadMask().getWidth(), this.pageSpread.getPageSpreadMask().getHeight() );
//            bufferLabel.setVisible( false );
//            javax.swing.JOptionPane.showMessageDialog( this, bufferLabel );
            layoutPane.add( pageSpreadMaskLabel, new Integer( 999 ) );

            if( this.pageSpread.getPageLayoutTemplate( PageSpread.LEFT_SPREAD_PAGE ) != null )
            {
                BufferedImage leftDecor = this.pageSpread.getPageLayoutTemplate( PageSpread.LEFT_SPREAD_PAGE ).getTemplateDecorations();
                if( leftDecor != null )
                {
                    ImageIcon leftDecorIcon = new ImageIcon( leftDecor );
                    JLabel leftDecorationLabel = new JLabel( leftDecorIcon );
                    leftDecorationLabel.setBounds( offsetX, offsetY, leftDecor.getWidth(), leftDecor.getHeight() );
                    layoutPane.add( leftDecorationLabel, new Integer( 998 ) );
                }
            }

            if( this.pageSpread.getPageLayoutTemplate( PageSpread.RIGHT_SPREAD_PAGE ) != null )
            {
                BufferedImage rightDecor = this.pageSpread.getPageLayoutTemplate( PageSpread.RIGHT_SPREAD_PAGE ).getTemplateDecorations();
                if( rightDecor != null )
                {
                    ImageIcon rightDecorIcon = new ImageIcon( rightDecor );
                    JLabel rightDecorationLabel = new JLabel( rightDecorIcon );
                    rightDecorationLabel.setBounds( offsetX + this.pageSpread.getPageSpreadMask().getWidth()/2, offsetY, rightDecor.getWidth(), rightDecor.getHeight() );
                    layoutPane.add( rightDecorationLabel, new Integer( 998 ) );
                }
            }

            System.out.println( "Page Spread : " + pageSpread.getImageFrames() );
            if( pageSpread.getImageFrames() != null && !pageSpread.getImageFrames().isEmpty() )
            {
                System.out.println( "Image Frames : " + pageSpread.getImageFrames().size() );
                for( Iterator<ImageFrame> it = pageSpread.getImageFrames().iterator(); it.hasNext(); )
                {
                    ImageFrame frame = it.next();
                    System.out.println( frame.getID() + " : " + frame.getOffset().x + ", " + frame.getOffset().y );
                    ImageFrameComponent component = new ImageFrameComponent(  frame );
                    component.setBounds( component.getBounds().x + offsetX, component.getBounds().y + offsetY, component.getBounds().width, component.getBounds().height );
                    layoutPane.add( component, new Integer( 100 ) );
                }
            }
            repaint();
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        layoutView = new javax.swing.JScrollPane();
        layoutPane = new javax.swing.JLayeredPane();
        jPanel1 = new javax.swing.JPanel();
        backButton = new javax.swing.JButton();
        forwardButton = new javax.swing.JButton();
        addButton = new javax.swing.JButton();

        layoutView.setViewportView(layoutPane);

        org.openide.awt.Mnemonics.setLocalizedText(backButton, org.openide.util.NbBundle.getMessage(KurvyLayoutTopComponent.class, "KurvyLayoutTopComponent.backButton.text")); // NOI18N
        backButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                backButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(forwardButton, org.openide.util.NbBundle.getMessage(KurvyLayoutTopComponent.class, "KurvyLayoutTopComponent.forwardButton.text")); // NOI18N
        forwardButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                forwardButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(KurvyLayoutTopComponent.class, "KurvyLayoutTopComponent.addButton.text")); // NOI18N
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(558, Short.MAX_VALUE)
                .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(5, 5, 5)
                .addComponent(addButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(forwardButton, javax.swing.GroupLayout.PREFERRED_SIZE, 77, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(636, 636, 636))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(forwardButton)
                    .addComponent(backButton)
                    .addComponent(addButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGap(10, 10, 10))
            .addComponent(layoutView, javax.swing.GroupLayout.DEFAULT_SIZE, 1448, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(layoutView, javax.swing.GroupLayout.DEFAULT_SIZE, 623, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void backButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_backButtonActionPerformed
    {//GEN-HEADEREND:event_backButtonActionPerformed
        previousPage();
    }//GEN-LAST:event_backButtonActionPerformed

    private void forwardButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_forwardButtonActionPerformed
    {//GEN-HEADEREND:event_forwardButtonActionPerformed
        nextPage();
    }//GEN-LAST:event_forwardButtonActionPerformed

    private void addButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_addButtonActionPerformed
    {//GEN-HEADEREND:event_addButtonActionPerformed
        // TODO add your handling code here:
        addPageSpread();
        BookLayoutTopComponent.findInstance().refresh();
    }//GEN-LAST:event_addButtonActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JButton backButton;
    private javax.swing.JButton forwardButton;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLayeredPane layoutPane;
    private javax.swing.JScrollPane layoutView;
    // End of variables declaration//GEN-END:variables

    /**
     * Gets default instance. Do not use directly: reserved for *.settings files only,
     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
     * To obtain the singleton instance, use {@link #findInstance}.
     */
    public static synchronized KurvyLayoutTopComponent getDefault()
    {
        if ( instance == null )
        {
            instance = new KurvyLayoutTopComponent();
        }
        return instance;
    }

    /**
     * Obtain the KurvyLayoutTopComponent instance. Never call {@link #getDefault} directly!
     */
    public static synchronized KurvyLayoutTopComponent findInstance()
    {
        TopComponent win = WindowManager.getDefault().findTopComponent( PREFERRED_ID );
        if ( win == null )
        {
            Logger.getLogger( KurvyLayoutTopComponent.class.getName() ).warning(
                    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system." );
            return getDefault();
        }
        if ( win instanceof KurvyLayoutTopComponent )
        {
            return (KurvyLayoutTopComponent) win;
        }
        Logger.getLogger( KurvyLayoutTopComponent.class.getName() ).warning(
                "There seem to be multiple components with the '" + PREFERRED_ID +
                "' ID. That is a potential source of errors and unexpected behavior." );
        return getDefault();
    }

    @Override
    public int getPersistenceType()
    {
        return TopComponent.PERSISTENCE_ONLY_OPENED;
    }

    @Override
    public void componentOpened()
    {
        // TODO add custom code on component opening
    }

    @Override
    public void componentClosed()
    {
        // TODO add custom code on component closing
    }

    void writeProperties( java.util.Properties p )
    {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty( "version", "1.0" );
        // TODO store your settings
    }

    Object readProperties( java.util.Properties p )
    {
        KurvyLayoutTopComponent singleton = KurvyLayoutTopComponent.getDefault();
        singleton.readPropertiesImpl( p );
        return singleton;
    }

    private void readPropertiesImpl( java.util.Properties p )
    {
        String version = p.getProperty( "version" );
        // TODO read your settings according to their version
    }

    @Override
    protected String preferredID()
    {
        return PREFERRED_ID;
    }

        public void dragEnter( DropTargetDragEvent dtde )
    {
        Transferable transferData = dtde.getTransferable();
        if( transferData instanceof PageLayoutTemplate ||
            transferData instanceof PageSpread )
        {
            dtde.acceptDrag( TransferHandler.COPY );
            System.out.println( "Drag Entered"  );
        }
    }

    public void dragOver( DropTargetDragEvent dtde )
    {
        Transferable transferData = dtde.getTransferable();
        if( transferData instanceof PageLayoutTemplate ||
            transferData instanceof PageSpread )
        {
            dtde.acceptDrag( TransferHandler.COPY );
            System.out.println( "Drag Overed"  );
        }
    }

    public void dropActionChanged( DropTargetDragEvent dtde )
    {
    }

    public void dragExit( DropTargetEvent dte )
    {
    }

    public void drop( DropTargetDropEvent dtde )
    {
        try
        {
            Transferable transferable = dtde.getTransferable();

            DataFlavor[] flavors = dtde.getCurrentDataFlavors();
            for( int i = 0; i < flavors.length; i++ )
            {
                Object transferData = transferable.getTransferData( flavors[ i ] );
                if ( transferData instanceof PageLayoutTemplate )
                {
                    dtde.acceptDrop( DnDConstants.ACTION_COPY );
                    this.pageSpread.setPageLayoutTemplate( (PageLayoutTemplate) transferData );
                    System.out.println( "DROP!!" );
                    this.layoutPage();
                    dtde.dropComplete( true );
                }
                else if( transferData instanceof PageSpread )
                {
                    dtde.acceptDrop( DnDConstants.ACTION_COPY );
                    setPageSpread( pageSpread );
                    System.out.println( "New DROP!!" );
                    this.layoutPage();
                    dtde.dropComplete( true );
                }
            }
        }
        catch ( UnsupportedFlavorException ex )
        {
            Exceptions.printStackTrace( ex );
        }
        catch ( IOException ex )
        {
            Exceptions.printStackTrace( ex );
        }
    }


}
